package com.lam.generator.entity;

import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import javax.validation.constraints.Size;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.lam.common.base.domain.BaseEntity;
import com.lam.common.components.dict.annotation.Dict;
import com.lam.common.components.dict.constant.DictTypeEnum;
import com.lam.common.utils.DateUtil;
import com.lam.common.utils.StringUtils;
import com.lam.common.validate.group.Add;
import com.lam.generator.common.constant.GeneratorConstant;

/**
 * 代码生成对象 gen_table
 * 
 * @author admin
 */
@TableName("gen_table")
public class GenTable implements BaseEntity {

	/** 主键 */
	@Null(groups = Add.class, message="id必须为空")
    @TableId(type = IdType.AUTO)
    private String id;
    
    /** 表名称 */
    @NotBlank(message = "表名称不能为空")
    @Size(max = 200, message = "表名称长度不能超过200个字符")
    private String tableName;

    /** 表描述 */
    @NotBlank(message = "表描述不能为空")
    @Size(max = 500, message = "表描述长度不能超过500个字符")
    private String tableComment;

    /** 实体类名称 */
    @NotBlank(message = "实体类名称不能为空")
    @Size(max = 100, message = "实体类名称长度不能超过100个字符")
    private String className;

    /** 实体类父类 */
    @Size(max = 300, message = "实体类父类长度不能超过300个字符")
    private String parentClassName;

    /** 代码模板（simple-单表操作, simpleTree-树表操作） */
    @NotBlank(message = "代码模板不能为空")
    @Size(max = 200, message = "代码模板长度不能超过200个字符")
    @Dict(dictCode = "template_type")
    private String templateType;

    /** 生成模块名 */
    @NotNull(message = "模块不能为空")
    @Size(max = 20, message = "模块度不能超过20个字符")
    @Dict(dictCode = "codeModule", dictType = DictTypeEnum.TABLE_DICT, targetField = "moduleName")
    private String codeModuleId;

    /** 生成业务名 */
    @NotBlank(message = "生成业务名不能为空")
    @Size(max = 30, message = "生成业务名长度不能超过30个字符")
    private String businessName;

    /** 生成功能名 */
    @NotBlank(message = "生成功能名不能为空")
    @Size(max = 50, message = "生成功能名长度不能超过50个字符")
    private String functionName;

    /** 生成功能作者 */
    @Size(max = 50, message = "生成功能作者长度不能超过50个字符")
    private String functionAuthor;

    /** 生成的功能列表 */
    @Size(max = 1000, message = "生成的功能列表长度不能超过1000个字符")
    private String functionList;

    /** 生成代码方式（1zip压缩包 2自定义路径） */
    @NotNull(message = "生成代码方式不能为空")
    @Dict(dictCode = "generate_type")
    private String genType;

    /** 生成路径（不填默认项目路径） */
    @Size(max = 200, message = "生成路径长度不能超过200个字符")
    private String genPath;

    /** 其它生成选项 */
    @Size(max = 1000, message = "其它生成选项长度不能超过1000个字符")
    private String options;

    /** 创建人 */
    private String createBy;

    /** 创建时间 */
    @JsonFormat(pattern = DateUtil.PATTERN_DEFAULT)
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;

    /** 修改人 */
    private String updateBy;

    /** 修改时间 */
    @JsonFormat(pattern = DateUtil.PATTERN_DEFAULT)
    @TableField(fill = FieldFill.UPDATE)
    private Date updateTime;

    /** 备注 */
    @Size(max = 500, message = "备注长度不能超过500个字符")
    private String remark;
    
    // =====  非数据库字段  ==========
    /** 实体类父类 */
    @TableField(exist = false)
	private Class<?> parentClass;
	/** 实体类父类的字段 */
    @TableField(exist = false)
	private List<String> parentFieldList;
	
    /** 代码模块 */
    @TableField(exist = false)
    private GenCodeModule codeModule;
    /** 主键信息 */
    @TableField(exist = false)
	private GenTableColumn pkColumn;
	/** 表列信息 */
	@Valid
	@TableField(exist = false)
	private List<GenTableColumn> columns;
	/** 其他信息 */
	@TableField(exist = false)
	private Map<String, Object> optionObject;
	
	@TableField(exist = false)
	private GenTableExtConfig extConfig;
	
	/** 上级菜单ID字段 */
	@TableField(exist = false)
	private String parentMenuId;
	/** 上级菜单名称字段 */
	@TableField(exist = false)
	private String parentMenuName;
	
	
	/** 唯一字段名称属性名 */
	@TableField(exist = false)
	private String uniqueField;
	/** 查询字段名称属性名 */
	@TableField(exist = false)
	private String uniqueQueryField;
	/** 条件SQL的字段属性名 */
	@TableField(exist = false)
	private String uniqueConditionField;
	
	// =====  非数据库字段  ==========
	
	public static GenTable create(DbTable dbTable) {
		GenTable genTable = new GenTable();
		genTable.setTableName(dbTable.getTableName());
		genTable.setTableComment(dbTable.getTableComment());
		return genTable;
	}

	public String getTableName() {
		return tableName;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	public String getTableComment() {
		return tableComment;
	}

	public void setTableComment(String tableComment) {
		this.tableComment = tableComment;
	}

	public String getClassName() {
		return className;
	}

	public void setClassName(String className) {
		this.className = className;
	}

	public String getBusinessName() {
		return businessName;
	}

	public void setBusinessName(String businessName) {
		this.businessName = businessName;
	}

	public String getFunctionName() {
		return functionName;
	}

	public void setFunctionName(String functionName) {
		this.functionName = functionName;
	}

	public String getFunctionAuthor() {
		return functionAuthor;
	}

	public void setFunctionAuthor(String functionAuthor) {
		this.functionAuthor = functionAuthor;
	}

	public String getGenType() {
		return genType;
	}

	public void setGenType(String genType) {
		this.genType = genType;
	}

	public String getGenPath() {
		return genPath;
	}

	public void setGenPath(String genPath) {
		this.genPath = genPath;
	}

	public GenTableColumn getPkColumn() {
		return pkColumn;
	}

	public void setPkColumn(GenTableColumn pkColumn) {
		this.pkColumn = pkColumn;
	}

	public List<GenTableColumn> getColumns() {
		return columns;
	}

	public void setColumns(List<GenTableColumn> columns) {
		this.columns = columns;
	}

	public String getOptions() {
		return options;
	}

	public void setOptions(String options) {
		this.options = options;
	}

	public boolean isSimpleTree() {
		return isSimpleTree(this.templateType);
	}

	public static boolean isSimpleTree(String templateType) {
		return templateType != null && StringUtils.equals(GeneratorConstant.TEMP_TYPE_SIMPLE_TREE, templateType);
	}

	public boolean isSimple() {
		return isSimple(this.templateType);
	}

	public static boolean isSimple(String tplCategory) {
		return tplCategory != null && StringUtils.equals(GeneratorConstant.TEMP_TYPE_SIMPLE, tplCategory);
	}

	public boolean hasFuncList() {
		return functionArray().contains("list");
	}
	public boolean hasFuncGetById() {
		return functionArray().contains("getById");
	}
	public boolean hasFuncUnique() {
		return functionArray().contains("unique");
	}
	public boolean hasFuncInsert() {
		return functionArray().contains("insert");
	}
	public boolean hasFuncUpdate() {
		return functionArray().contains("update");
	}
	public boolean hasFuncDetail() {
		return functionArray().contains("detail");
	}
	public boolean hasFuncDelete() {
		return functionArray().contains("delete");
	}
	public boolean hasFuncImport() {
		return functionArray().contains("import");
	}
	public boolean hasFuncExport() {
		return functionArray().contains("export");
	}

	private List<String> functionArray() {
		if (StringUtils.isNotBlank(functionList)) {
			return Arrays.asList(functionList.split(","));
		}else{
			return Collections.emptyList();
		}
	}
	
	public String getFunctionList() {
		return functionList;
	}
	
	public void setFunctionList(String functionList) {
		this.functionList = functionList;
	}

	public Class<?> getParentClass() {
		return parentClass;
	}

	public void setParentClass(Class<?> parentClass) {
		this.parentClass = parentClass;
	}

	public String getParentClassName0() {
		if(StringUtils.isBlank(parentClassName)) {
			return "";
		}
		int index = parentClassName.lastIndexOf(".");
		String simpleName = parentClassName.substring(index + 1);
		return simpleName.equals("BaseTree")? String.format("BaseTree<%s>", className):simpleName;
	}

	public String getParentClassName() {
		return parentClassName;
	}

	public void setParentClassName(String parentClassName) {
		this.parentClassName = parentClassName;
	}

	public List<String> getParentFieldList() {
		return parentFieldList;
	}

	public void setParentFieldList(List<String> parentFieldList) {
		this.parentFieldList = parentFieldList;
	}

	public String getCreateBy() {
		return createBy;
	}

	public void setCreateBy(String createBy) {
		this.createBy = createBy;
	}

	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	public String getUpdateBy() {
		return updateBy;
	}

	public void setUpdateBy(String updateBy) {
		this.updateBy = updateBy;
	}

	public Date getUpdateTime() {
		return updateTime;
	}

	public void setUpdateTime(Date updateTime) {
		this.updateTime = updateTime;
	}

	public String getRemark() {
		return remark;
	}

	public void setRemark(String remark) {
		this.remark = remark;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public Map<String, Object> getOptionObject() {
		return optionObject;
	}

	public void setOptionObject(Map<String, Object> optionObject) {
		this.optionObject = optionObject;
	}

	public String getUniqueField() {
		return uniqueField;
	}

	public void setUniqueField(String uniqueField) {
		this.uniqueField = uniqueField;
	}

	public String getUniqueQueryField() {
		return uniqueQueryField;
	}

	public void setUniqueQueryField(String uniqueQueryField) {
		this.uniqueQueryField = uniqueQueryField;
	}

	public String getUniqueConditionField() {
		return uniqueConditionField;
	}

	public void setUniqueConditionField(String uniqueConditionField) {
		this.uniqueConditionField = uniqueConditionField;
	}

	public String getParentMenuId() {
		return parentMenuId;
	}

	public void setParentMenuId(String parentMenuId) {
		this.parentMenuId = parentMenuId;
	}

	public String getParentMenuName() {
		return parentMenuName;
	}

	public void setParentMenuName(String parentMenuName) {
		this.parentMenuName = parentMenuName;
	}

	public GenCodeModule getCodeModule() {
		return codeModule;
	}

	public void setCodeModule(GenCodeModule codeModule) {
		this.codeModule = codeModule;
	}

	public String getCodeModuleId() {
		return codeModuleId;
	}

	public void setCodeModuleId(String codeModuleId) {
		this.codeModuleId = codeModuleId;
	}

	public GenTableExtConfig getExtConfig() {
		return extConfig;
	}

	public void setExtConfig(GenTableExtConfig extConfig) {
		this.extConfig = extConfig;
	}

	public String getTemplateType() {
		return templateType;
	}

	public void setTemplateType(String templateType) {
		this.templateType = templateType;
	}


}